Installation

To install Destin2, run:

devtools::install_github("yuchaojiang/Destin2/package")

Introduction

This vignette will demonstrate the utility of the Destin2 package through analysis of a single-cell ATAC-seq dataset of adult mouse brain cells provided by 10x Genomics. Links to the raw data as well as code used for pre-processing and Signac-based downstream analysis can be found on the corresponding Signac vignette. For brevity, we omit the details here; we encourage the invested reader to examine the Signac vignette.

First, we load in Destin2 as well as the other packages we will be using for this vignette.

library(Destin2)
library(Signac)
library(Seurat)
library(GenomeInfoDb)
library(EnsDb.Mmusculus.v79)
library(BSgenome.Mmusculus.UCSC.mm10)
library(TFBSTools)
library(JASPAR2020)
library(cisTopic)
library(mogsa)
library(ggplot2)
library(patchwork)
library(clustree)
library(slingshot)

QC and Pre-Processing

Next, we load in the peak/cell matrix and cell metadata and perform quality control pre-processing. The following files are used in this vignette, available through 10X Genomics:

set.seed(1234)

#Reference genome
genome=BSgenome.Mmusculus.UCSC.mm10
ensdb=EnsDb.Mmusculus.v79

# load the RNA and ATAC data
counts <- Read10X_h5("../data/atac_v1_adult_brain_fresh_5k_filtered_peak_bc_matrix.h5")
metadata <- read.csv(
  file = "../data/atac_v1_adult_brain_fresh_5k_singlecell.csv",
  header = TRUE,
  row.names = 1
)
fragpath <- "../data/atac_v1_adult_brain_fresh_5k_fragments.tsv.gz"

chrom_assay <- CreateChromatinAssay(
  counts = counts,
  sep = c(":", "-"),
  genome = 'mm10',
  fragments = fragpath,
  min.cells = 1
)

brain <- CreateSeuratObject(
  counts = chrom_assay,
  assay = "peaks",
  project = 'ATAC',
  meta.data = metadata
)

# get gene annotations
annotations <- GetGRangesFromEnsDb(ensdb = ensdb)
seqlevelsStyle(annotations) <- "UCSC"
Annotation(brain) <- annotations


brain <- NucleosomeSignal(brain)
brain <- TSSEnrichment(brain, fast = F)

brain$pct_reads_in_peaks <- brain$peak_region_fragments / brain$passed_filters * 100
brain$blacklist_ratio <- brain$blacklist_region_fragments / brain$peak_region_fragments
brain$high.tss <- ifelse(brain$TSS.enrichment > 2, 'High', 'Low')
brain$nucleosome_group <- ifelse(brain$nucleosome_signal > 4, 'NS > 4', 'NS < 4')

brain <- subset(
  x = brain,
  subset = peak_region_fragments > 3000 &
    peak_region_fragments < 100000 &
    pct_reads_in_peaks > 40 &
    blacklist_ratio < 0.025 &
    nucleosome_signal < 4 &
    TSS.enrichment > 2
)

Unimodal Analyses

Destin2 provides methods for conducting and integrating cross-modality analyses. In order to do so, we consider the following unimodal analyses.

The first analysis method will be to normalize and reduce the peak/cell matrix using latent semantic indexing (LSI), followed by graph-based clustering.

brain <- RunTFIDF(brain)
brain <- FindTopFeatures(brain, min.cutoff = 'q0')
brain <- RunSVD(brain) # This by default returns an lsi reduction

brain <- FindNeighbors(object = brain, reduction = 'lsi', dims = 2:30)
brain <- FindClusters(object = brain, verbose = FALSE, algorithm = 3)

The second unimodal analysis method will be a gene activity matrix derived from this scATAC-seq data. Here we use the GeneActivity function provided by Signac; we note that there exist alternatives such as MAESTRO that could also be used.

gene.activities <- GeneActivity(brain)
# This can be substituted with MAESTRO's regulatory potential model

# add the gene activity matrix to the Seurat object as a new assay and normalize it
brain[['RNA']] <- CreateAssayObject(counts = gene.activities)
brain <- NormalizeData(
  object = brain,
  assay = 'RNA',
  normalization.method = 'LogNormalize',
  scale.factor = median(brain$nCount_RNA)
)

For downstream analysis, we reduce the dimension of his matrix using PCA.

DefaultAssay(brain) <- 'RNA'

brain <- FindVariableFeatures(brain, selection.method = "vst", nfeatures = 2000)
brain <- ScaleData(brain, features = rownames(brain))
brain <- RunPCA(brain, features = VariableFeatures(brain), 
               reduction.name = 'activity.pca',  reduction.key = 'activitypca_', verbose = FALSE)

Downstream analysis oftentimes makes use of transferred cell type labels. We follow the procedure outlined in the Signac vignette.

allen_rna <- readRDS("../data/allen_brain.rds")

transfer.anchors <- FindTransferAnchors(
  reference = allen_rna,
  query = brain,
  reduction = 'cca',
  dims = 1:40
)

predicted.labels <- TransferData(
  anchorset = transfer.anchors,
  refdata = allen_rna$subclass,
  weight.reduction = brain[['lsi']],
  dims = 2:30
)

brain <- AddMetaData(object = brain, metadata = predicted.labels)

for(i in levels(brain)) {
  cells_to_reid <- WhichCells(brain, idents = i)
  newid <- names(sort(table(brain$predicted.id[cells_to_reid]),decreasing=TRUE))[1]
  Idents(brain, cells = cells_to_reid) <- newid
}

# Remove cells with low label-transfer scores
brain=subset(brain, cells=which(brain$prediction.score.max>0.8))

Next, we compute a cell by motif activity matrix using chromVAR. Full details of the method can be found in the corresponding paper.

# Get a list of motif position frequency matrices from the JASPAR database
pfm <- getMatrixSet(
  x = JASPAR2020,
  opts = list(collection = "CORE", tax_group = 'vertebrates', all_versions = FALSE)
)

# add motif information
DefaultAssay(brain)='peaks'
brain <- AddMotifs(
  object = brain,
  genome = genome,
  pfm = pfm
)

# Computing motif activities
brain <- RunChromVAR(
  object = brain,
  genome = genome,
  new.assay.name = 'MOTIF'
)

Similarly, we reduce this cell by motif matrix using PCA.

DefaultAssay(brain) <- 'MOTIF'
#Using PCA dimensional reduction on motif modality and put it into Seurat Object
#Choice of 50 PCs here is arbitrary
pca_motif<-prcomp(t(brain@assays[["MOTIF"]]@data))$x[,1:50]
brain[["motif.pca"]] <- CreateDimReducObject(embeddings = pca_motif, key = "motifpca_", assay = "MOTIF")

The final unimodal analysis we will consider is topic modeling using cisTopic. Full details for the method can be found on their github. We note that the number of topics chosen as well as other computing parameters were chosen based on the computing power at hand; one may need to adjust these as needed based on individual computing capabilities.

DefaultAssay(brain) <- 'peaks'
temp = brain@assays$peaks@counts
rownames(temp)=GRangesToString(brain@assays$peaks@ranges, sep=c(':','-'))
cisTopicbrain = createcisTopicObject(count.matrix = temp)
rm(temp)

cisTopicObject <- runWarpLDAModels(cisTopicbrain, topic=c(5, 10, 20, 25, 30, 40), seed=987, nCores=6, iterations = 500, addModels=FALSE)
## [1] "Exporting data..."
## [1] "Run models..."
cisTopicObject <- selectModel(cisTopicObject, type = 'derivative')
## [1] "Are these CGS models? Please, use type=\"maximum\""
cisTopicObject <- runUmap(cisTopicObject, target='cell', seed=123, method='Probability')

dim(cisTopicObject@selected.model$topics)
## [1]     40 156997
dim(cisTopicObject@selected.model$document_expects)
## [1]   40 2276
brain[['lda']] <- CreateDimReducObject(embeddings = t(cisTopicObject@selected.model$document_expects), key = "lda_", assay = "peaks")

Cross-Modality Analyses

Destin2 offers three options for cross-modality integration: consensus PCA, multiple CCA, and weighted nearest neighbor. These are implemented in the functions GetConsensusPCA, GetMultiCCA, and FindMultiModalNeighbors from the Seurat V4 package.

GetConsensusPCA and GetMultiCCA have a similar set of main parameters:

## list of dimensional reduction objects in brain
reductions <- list('lsi','lda','activity.pca','motif.pca')
## dimensions to use for each dimensionality reduction object; we choose 30 for this demonstration
## we drop first PC from lsi based on correlation with sequencing depth
reduction_dims <- list(2:31, 1:30, 1:30, 1:30)

brain <- GetConsensusPCA(brain, reduction.list=reductions,
                  dims.list = reduction_dims,
                  reduction.name = 'consensus.pca',
                  reduction.key = "consensuspca_", 
                  assay = "peaks")

brain <- GetMultiCCA(brain, reduction.list=reductions,
                         dims.list = reduction_dims,
                         reduction.name = 'multicca.pca',
                         reduction.key = "multiccapca_",
                         assay = "peaks")

brain <- FindMultiModalNeighbors(brain, reduction.list=reductions,
                                 dims.list = reduction_dims, verbose=FALSE)

brain
## An object of class Seurat 
## 179757 features across 2276 samples within 3 assays 
## Active assay: peaks (157203 features, 157203 variable features)
##  2 other assays present: RNA, MOTIF
##  6 dimensional reductions calculated: lsi, activity.pca, motif.pca, lda, consensus.pca, multicca.pca

We demonstrate the utility of the cross-modality framework that Destin2 offers through graph-based clustering and non-linear dimension reduction and visualization using UMAP.

########################
#### Consensus PCA
########################
brain <- RunUMAP(brain, dims = 1:30, reduction='consensus.pca', 
               reduction.name='consensus.umap', reduction.key = 'consensusumap_', verbose = FALSE)

DefaultAssay(brain)='peaks'
brain <- FindNeighbors(object = brain, reduction = 'consensus.pca', dims = 1:30, verbose = FALSE, graph.name=c('consensuspca_nn','consensuspca_snn'))
brain <- FindClusters(object = brain, algorithm = 1, verbose = FALSE, graph.name='consensuspca_snn')
  
brain$consensus_clusters=brain$seurat_clusters
p1=DimPlot(object = brain, group.by='consensus_clusters', label = TRUE, reduction = 'consensus.umap') + NoLegend()+ggtitle('Consensus PCA')
p2=DimPlot(object = brain, group.by='predicted.id', label = TRUE, reduction = 'consensus.umap') + NoLegend()+ggtitle('Consensus PCA')
p1+p2

########################
#### MultiCCA
########################
brain <- RunUMAP(brain, dims = 1:30, reduction='multicca.pca', 
               reduction.name='multicca.umap', reduction.key = 'multiccaumap_', verbose = FALSE)
brain <- FindNeighbors(object = brain, reduction = 'multicca.pca', dims = 1:30, verbose = FALSE, graph.name=c('multicca_nn','multicca_snn'))
brain <- FindClusters(object = brain, algorithm = 1, verbose = FALSE, graph.name='multicca_snn')
  
brain$cc_clusters = brain$seurat_clusters
p1=DimPlot(object = brain, label = TRUE, group.by='cc_clusters',reduction = 'multicca.umap') + NoLegend()+ggtitle('MultiCCA')
p2=DimPlot(object = brain, group.by='predicted.id',label = TRUE, reduction = 'multicca.umap') + NoLegend() +ggtitle('MultiCCA')
p1+p2

########################
#### Weighted NN
########################

brain <- RunUMAP(brain, nn.name = "weighted.nn", reduction.name = "wnn.umap", reduction.key = "wnnUMAP_")
## 18:51:11 UMAP embedding parameters a = 0.9922 b = 1.112
## 18:51:12 Commencing smooth kNN distance calibration using 1 thread with target n_neighbors = 20
## 18:51:15 Found 2 connected components, falling back to random initialization
## 18:51:15 Initializing from uniform random
## 18:51:15 Commencing optimization for 500 epochs, with 63142 positive edges
## 18:51:19 Optimization finished
brain <- FindClusters(brain, graph.name = "wsnn", algorithm = 3, resolution = 2, verbose = FALSE)
brain$wnn_clusters = brain$seurat_clusters

p1=DimPlot(object = brain, label = TRUE, group.by='wnn_clusters',reduction = 'wnn.umap') + NoLegend()+ggtitle('WNN')
p2=DimPlot(object = brain, group.by='predicted.id',label = TRUE, reduction = 'wnn.umap') + NoLegend() +ggtitle('WNN')
p1+p2

For further clustering inference, the clustree allows us to build clustering trees and measure the stability of clusters as resolution increases.

#########################################################
  ##  clustree to determine the number of clusters / resolution
  #########################################################

  resolution.range <- seq(from = 0.2, to = 1.2, by = 0.2)
  brain <- FindClusters(object = brain, algorithm = 1, verbose = FALSE, resolution = resolution.range, graph.name='consensuspca_snn')
  brain.cpca.clustree=clustree(brain, prefix = 'consensuspca_snn_res.')
  p1=brain.cpca.clustree
  # The stability index from the SC3 package (Kiselev et al. 2017) measures the stability of clusters across resolutions.
  # The stability index is automatically calculated when a clustering tree is built.
  brain.cpca.clustree=clustree(brain, prefix = 'consensuspca_snn_res.', node_colour = "sc3_stability")
  p2=brain.cpca.clustree
  p1+p2

  resolution.range <- seq(from = 0.2, to = 1.2, by = 0.2)
  brain <- FindClusters(object = brain, algorithm = 1, verbose = FALSE, resolution = resolution.range, graph.name='multicca_snn')
  brain.mcca.clustree=clustree(brain, prefix = 'multicca_snn_res.')
  p1=brain.mcca.clustree
  brain.mcca.clustree=clustree(brain, prefix = 'multicca_snn_res.', node_colour = "sc3_stability")
  p2=brain.mcca.clustree
  p1+p2

  resolution.range <- seq(from = 0.2, to = 1.2, by = 0.2)
  brain <- FindClusters(object = brain, algorithm = 1, resolution = resolution.range, verbose = FALSE, graph.name = "wsnn")
  brain.wnn.clustree=clustree(brain, prefix = 'wsnn_res.')
  p1=brain.wnn.clustree
  brain.wnn.clustree=clustree(brain, prefix = 'wsnn_res.', node_colour = "sc3_stability")
  p2=brain.wnn.clustree
  p1+p2

The final part of our analysis uses the Slingshot package to perform trajectory inference. The GetSlingshot function provides a convenient wrapper to this package. A vignette on Slingshot can be found here.

GetSlingshot takes the following parameters:

CPCALineages <- GetSlingshot(brain, reduction.to.construct = 'consensus.pca',
                      reduction.to.plot='consensus.umap',
                      cluster='consensus_clusters', 
                      predicted.id='predicted.id',
                      generate.plot = TRUE)

CPCALineages
## class: SlingshotDataSet 
## 
##  Samples Dimensions
##     2276          2
## 
## lineages: 9 
## Lineage1: 0  8  2  13  10  1  6  5  16  
## Lineage2: 0  8  2  13  10  1  6  5  17  
## Lineage3: 0  8  2  13  10  1  6  12  
## Lineage4: 0  8  2  13  10  1  4  14  
## Lineage5: 0  8  2  13  10  1  6  11  
## Lineage6: 0  8  2  13  10  9  
## Lineage7: 0  8  2  13  15  
## Lineage8: 0  8  2  7  18  
## Lineage9: 0  8  2  3  
## 
## curves: 0
MCCALineages <- GetSlingshot(brain, reduction.to.construct = 'multicca.pca',
                      reduction.to.plot='multicca.umap',
                      cluster='cc_clusters', 
                      predicted.id='predicted.id',
                      generate.plot = TRUE)

MCCALineages
## class: SlingshotDataSet 
## 
##  Samples Dimensions
##     2276          2
## 
## lineages: 8 
## Lineage1: 0  7  2  12  9  1  4  11  6  5  15  
## Lineage2: 0  7  2  12  9  1  4  11  6  5  16  
## Lineage3: 0  7  2  12  9  1  4  11  6  14  
## Lineage4: 0  7  2  12  9  1  4  11  6  10  
## Lineage5: 0  7  2  12  9  8  
## Lineage6: 0  7  2  12  9  17  
## Lineage7: 0  7  2  12  13  
## Lineage8: 0  7  2  3  
## 
## curves: 0
sessionInfo()
## R version 4.2.1 (2022-06-23)
## Platform: x86_64-apple-darwin17.0 (64-bit)
## Running under: macOS Catalina 10.15.7
## 
## Matrix products: default
## BLAS:   /Library/Frameworks/R.framework/Versions/4.2/Resources/lib/libRblas.0.dylib
## LAPACK: /Library/Frameworks/R.framework/Versions/4.2/Resources/lib/libRlapack.dylib
## 
## locale:
## [1] en_US.UTF-8/en_US.UTF-8/en_US.UTF-8/C/en_US.UTF-8/en_US.UTF-8
## 
## attached base packages:
## [1] stats4    stats     graphics  grDevices utils     datasets  methods  
## [8] base     
## 
## other attached packages:
##  [1] umap_0.2.9.0                       slingshot_2.4.0                   
##  [3] TrajectoryUtils_1.4.0              SingleCellExperiment_1.18.1       
##  [5] SummarizedExperiment_1.26.1        MatrixGenerics_1.8.1              
##  [7] matrixStats_0.62.0                 princurve_2.1.6                   
##  [9] clustree_0.5.0                     ggraph_2.1.0                      
## [11] patchwork_1.1.2                    ggplot2_3.3.6                     
## [13] mogsa_1.30.0                       cisTopic_0.3.0                    
## [15] JASPAR2020_0.99.10                 TFBSTools_1.34.0                  
## [17] BSgenome.Mmusculus.UCSC.mm10_1.4.3 BSgenome_1.64.0                   
## [19] rtracklayer_1.56.1                 Biostrings_2.64.1                 
## [21] XVector_0.36.0                     EnsDb.Mmusculus.v79_2.99.0        
## [23] ensembldb_2.20.2                   AnnotationFilter_1.20.0           
## [25] GenomicFeatures_1.48.4             AnnotationDbi_1.58.0              
## [27] Biobase_2.56.0                     GenomicRanges_1.48.0              
## [29] GenomeInfoDb_1.32.4                IRanges_2.30.1                    
## [31] S4Vectors_0.34.0                   BiocGenerics_0.42.0               
## [33] sp_1.5-0                           SeuratObject_4.1.2                
## [35] Seurat_4.2.0                       Signac_1.8.0                      
## [37] Destin2_0.0.0.9000                
## 
## loaded via a namespace (and not attached):
##   [1] Hmisc_4.7-1                 ica_1.0-3                  
##   [3] corpcor_1.6.10              RcppRoll_0.3.0             
##   [5] Rsamtools_2.12.0            foreach_1.5.2              
##   [7] lmtest_0.9-40               crayon_1.5.2               
##   [9] spatstat.core_2.4-4         MASS_7.3-58.1              
##  [11] nlme_3.1-160                backports_1.4.1            
##  [13] rlang_1.0.6                 svd_0.5.2                  
##  [15] ROCR_1.0-11                 irlba_2.3.5.1              
##  [17] filelock_1.0.2              BiocParallel_1.30.4        
##  [19] rjson_0.2.21                CNEr_1.32.0                
##  [21] bit64_4.0.5                 glue_1.6.2                 
##  [23] poweRlaw_0.70.6             text2vec_0.6.2             
##  [25] sctransform_0.3.5           chromVAR_1.18.0            
##  [27] parallel_4.2.1              spatstat.sparse_2.1-1      
##  [29] spatstat.geom_2.4-0         tidyselect_1.2.0           
##  [31] fitdistrplus_1.1-8          XML_3.99-0.11              
##  [33] tidyr_1.2.1                 zoo_1.8-11                 
##  [35] GenomicAlignments_1.32.1    xtable_1.8-4               
##  [37] magrittr_2.0.3              evaluate_0.17              
##  [39] cli_3.4.1                   zlibbioc_1.42.0            
##  [41] rstudioapi_0.14             miniUI_0.1.1.1             
##  [43] bslib_0.4.0                 rpart_4.1.16               
##  [45] fastmatch_1.1-3             shiny_1.7.2                
##  [47] xfun_0.34                   askpass_1.1                
##  [49] cluster_2.1.4               caTools_1.18.2             
##  [51] tidygraph_1.2.2             doSNOW_1.0.20              
##  [53] KEGGREST_1.36.3             tibble_3.1.8               
##  [55] ggrepel_0.9.1               biovizBase_1.44.0          
##  [57] listenv_0.8.0               TFMPvalue_0.0.8            
##  [59] lda_1.4.2                   png_0.1-7                  
##  [61] future_1.28.0               withr_2.5.0                
##  [63] bitops_1.0-7                ggforce_0.4.1              
##  [65] plyr_1.8.7                  GSEABase_1.58.0            
##  [67] pracma_2.4.2                pillar_1.8.1               
##  [69] gplots_3.1.3                cachem_1.0.6               
##  [71] hdf5r_1.3.7                 graphite_1.42.0            
##  [73] DelayedMatrixStats_1.18.2   vctrs_0.4.2                
##  [75] ellipsis_0.3.2              generics_0.1.3             
##  [77] tools_4.2.1                 foreign_0.8-83             
##  [79] feather_0.3.5               mlapi_0.1.1                
##  [81] munsell_0.5.0               tweenr_2.0.2               
##  [83] DelayedArray_0.22.0         fastmap_1.1.0              
##  [85] compiler_4.2.1              abind_1.4-5                
##  [87] httpuv_1.6.6                plotly_4.10.0              
##  [89] rgeos_0.5-9                 GenomeInfoDbData_1.2.8     
##  [91] gridExtra_2.3               lattice_0.20-45            
##  [93] deldir_1.0-6                snow_0.4-4                 
##  [95] utf8_1.2.2                  later_1.3.0                
##  [97] dplyr_1.0.10                BiocFileCache_2.4.0        
##  [99] jsonlite_1.8.2              scales_1.2.1               
## [101] graph_1.74.0                pbapply_1.5-0              
## [103] sparseMatrixStats_1.8.0     nabor_0.5.0                
## [105] genefilter_1.78.0           lazyeval_0.2.2             
## [107] promises_1.2.0.1            latticeExtra_0.6-30        
## [109] R.utils_2.12.0              goftest_1.2-3              
## [111] spatstat.utils_3.0-1        reticulate_1.26            
## [113] checkmate_2.1.0             rmarkdown_2.17             
## [115] cowplot_1.1.1               Rtsne_0.16                 
## [117] dichromat_2.0-0.1           uwot_0.1.14                
## [119] igraph_1.3.5                survival_3.4-0             
## [121] yaml_2.3.6                  htmltools_0.5.3            
## [123] memoise_2.0.1               VariantAnnotation_1.42.1   
## [125] BiocIO_1.6.0                lgr_0.4.4                  
## [127] graphlayouts_0.8.3          viridisLite_0.4.1          
## [129] arrow_9.0.0.2               digest_0.6.30              
## [131] assertthat_0.2.1            RhpcBLASctl_0.21-247.1     
## [133] mime_0.12                   rappdirs_0.3.3             
## [135] RSQLite_2.2.18              future.apply_1.9.1         
## [137] data.table_1.14.4           blob_1.2.3                 
## [139] R.oo_1.25.0                 labeling_0.4.2             
## [141] splines_4.2.1               Formula_1.2-4              
## [143] ProtGenerics_1.28.0         RCurl_1.98-1.9             
## [145] hms_1.1.2                   colorspace_2.0-3           
## [147] base64enc_0.1-3             nnet_7.3-18                
## [149] sass_0.4.2                  Rcpp_1.0.9                 
## [151] RANN_2.6.1                  fansi_1.0.3                
## [153] tzdb_0.3.0                  parallelly_1.32.1          
## [155] R6_2.5.1                    grid_4.2.1                 
## [157] ggridges_0.5.4              lifecycle_1.0.3            
## [159] curl_4.3.3                  motifmatchr_1.18.0         
## [161] leiden_0.4.3                jquerylib_0.1.4            
## [163] Matrix_1.5-1                RcppAnnoy_0.0.19           
## [165] RColorBrewer_1.1-3          iterators_1.0.14           
## [167] stringr_1.4.1               htmlwidgets_1.5.4          
## [169] polyclip_1.10-4             biomaRt_2.52.0             
## [171] purrr_0.3.5                 seqLogo_1.62.0             
## [173] mgcv_1.8-40                 globals_0.16.1             
## [175] rsparse_0.5.1               openssl_2.0.4              
## [177] htmlTable_2.4.1             spatstat.random_2.2-0      
## [179] progressr_0.11.0            codetools_0.2-18           
## [181] GO.db_3.15.0                gtools_3.9.3               
## [183] prettyunits_1.1.1           dbplyr_2.2.1               
## [185] RSpectra_0.16-1             R.methodsS3_1.8.2          
## [187] gtable_0.3.1                DBI_1.1.3                  
## [189] highr_0.9                   tensor_1.5                 
## [191] httr_1.4.4                  KernSmooth_2.23-20         
## [193] RcisTarget_1.16.0           stringi_1.7.8              
## [195] progress_1.2.2              reshape2_1.4.4             
## [197] farver_2.1.1                annotate_1.74.0            
## [199] viridis_0.6.2               DT_0.26                    
## [201] xml2_1.3.3                  AUCell_1.18.1              
## [203] restfulr_0.0.15             interp_1.1-3               
## [205] readr_2.1.3                 float_0.3-0                
## [207] scattermore_0.8             bit_4.0.4                  
## [209] jpeg_0.1-9                  spatstat.data_2.2-0        
## [211] pkgconfig_2.0.3             DirichletMultinomial_1.38.0
## [213] knitr_1.40